<script setup>
import { ref, onMounted } from 'vue'
import CodeBlock from '@components/CodeBlock.vue'

// 内部状态 - 这些不会自动暴露给父组件
const internalCount = ref(0)
const startTime = ref(null)
const isRunning = ref(false)

// 内部方法
const updateTimer = () => {
  if (isRunning.value && startTime.value) {
    const elapsed = Math.floor((Date.now() - startTime.value) / 1000)
    internalCount.value = elapsed
    setTimeout(updateTimer, 1000)
  }
}

// 公共方法和状态 - 通过defineExpose暴露
const startTimer = () => {
  if (!isRunning.value) {
    startTime.value = Date.now() - internalCount.value * 1000
    isRunning.value = true
    updateTimer()
  }
}

const stopTimer = () => {
  isRunning.value = false
}

const resetTimer = () => {
  isRunning.value = false
  internalCount.value = 0
  startTime.value = null
}

const getStatus = () => {
  return {
    isRunning: isRunning.value,
    count: internalCount.value,
    secondsElapsed: internalCount.value,
    minutesElapsed: Math.floor(internalCount.value / 60)
  }
}

// 使用defineExpose暴露公共接口
defineExpose({
  // 暴露的方法
  startTimer,
  stopTimer,
  resetTimer,
  getStatus,
  
  // 暴露的响应式状态
  timerCount: internalCount,
  isActive: isRunning
})

// 演示信息对象，避免引号和HTML标签解析问题
const exposeInfo = {
  implementation: {
    title: '子组件实现 (使用defineExpose)',
    description: '在子组件中定义并暴露公共接口',
    features: [
      '定义内部状态和方法',
      '使用defineExpose显式声明公共接口',
      '暴露方法和响应式状态'
    ]
  },
  parentUsage: {
    title: '父组件使用方式',
    description: '父组件通过ref访问子组件暴露的接口',
    features: [
      '创建组件引用',
      '调用子组件暴露的方法',
      '访问子组件暴露的状态'
    ]
  }
}

// 模拟父组件操作
const statusInfo = ref(null)

const simulateParentAccess = () => {
  // 模拟父组件通过ref访问子组件的公共接口
  statusInfo.value = getStatus()
}
</script>

<template>
  <div class="compiler-expose-demo">
    <h3>defineExpose 演示</h3>
    
    <div class="demo-content">
      <div class="timer-demo">
        <h4>计时器演示</h4>
        
        <div class="timer-display">
          <div class="timer-value">
            {{ Math.floor(internalCount / 60).toString().padStart(2, '0') }}:
            {{ (internalCount % 60).toString().padStart(2, '0') }}
          </div>
          
          <div class="timer-controls">
            <button 
              @click="startTimer" 
              :disabled="isRunning" 
              class="demo-button start"
            >
              开始
            </button>
            
            <button 
              @click="stopTimer" 
              :disabled="!isRunning" 
              class="demo-button stop"
            >
              停止
            </button>
            
            <button 
              @click="resetTimer" 
              class="demo-button reset"
            >
              重置
            </button>
          </div>
        </div>
        
        <div class="parent-simulation">
          <h4>模拟父组件访问</h4>
          <button @click="simulateParentAccess" class="demo-button">
            获取组件状态
          </button>
          
          <div v-if="statusInfo" class="status-info">
            <p><strong>运行状态:</strong> {{ statusInfo.isRunning ? '运行中' : '已停止' }}</p>
            <p><strong>已用时间:</strong> {{ statusInfo.secondsElapsed }} 秒</p>
            <p><strong>已用分钟:</strong> {{ statusInfo.minutesElapsed }} 分钟</p>
          </div>
        </div>
      </div>
      
      <div class="code-examples">
        <div class="code-section">
          <h4>{{ exposeInfo.implementation.title }}</h4>
          <p>{{ exposeInfo.implementation.description }}</p>
          <ul>
            <li v-for="(feature, index) in exposeInfo.implementation.features" :key="index">
              • {{ feature }}
            </li>
          </ul>
        </div>
        
        <div class="code-section">
          <h4>{{ exposeInfo.parentUsage.title }}</h4>
          <p>{{ exposeInfo.parentUsage.description }}</p>
          <ul>
            <li v-for="(feature, index) in exposeInfo.parentUsage.features" :key="index">
              • {{ feature }}
            </li>
          </ul>
        </div>
      </div>
    </div>
    
    <div class="explanation">
      <h4>defineExpose 的优势</h4>
      <ul>
        <li>✅ 显式声明组件的公共接口，提高代码可维护性</li>
        <li>✅ 避免依赖内部实现细节，增强封装性</li>
        <li>✅ 更好的类型安全性，特别是在TypeScript项目中</li>
        <li>✅ 清晰的组件边界，明确哪些方法和属性可以被外部访问</li>
        <li>✅ 支持暴露响应式状态，父组件可以直接访问</li>
      </ul>
    </div>
    
    <div class="best-practices">
      <h4>最佳实践</h4>
      <div class="practice-tips">
        <div class="tip-item">
          <h5>🔹 最小暴露原则</h5>
          <p>只暴露必要的方法和属性，保持内部实现的封装性</p>
        </div>
        
        <div class="tip-item">
          <h5>🔹 命名一致性</h5>
          <p>暴露的接口使用清晰、一致的命名，便于理解和使用</p>
        </div>
        
        <div class="tip-item">
          <h5>🔹 TypeScript集成</h5>
          <p>结合TypeScript为暴露的接口提供完整的类型定义</p>
        </div>
        
        <div class="tip-item">
          <h5>🔹 避免过度暴露</h5>
          <p>优先使用props和events进行组件通信，只在必要时使用ref访问</p>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.compiler-expose-demo {
  background-color: white;
  border-radius: 8px;
  padding: 1.5rem;
}

.compiler-expose-demo h3 {
  color: #42b883;
  margin-bottom: 1rem;
}

.demo-content {
  margin-bottom: 1.5rem;
}

.timer-demo {
  background-color: #f8f9fa;
  padding: 1.5rem;
  border-radius: 8px;
  border-left: 4px solid #42b883;
  margin-bottom: 2rem;
}

.timer-demo h4 {
  margin-top: 0;
  margin-bottom: 1rem;
  color: #333;
}

.timer-display {
  text-align: center;
  margin-bottom: 2rem;
}

.timer-value {
  font-size: 3rem;
  font-weight: bold;
  color: #42b883;
  font-family: 'Monaco', 'Menlo', monospace;
  margin-bottom: 1.5rem;
  padding: 1rem;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.timer-controls {
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
}

.demo-button {
  padding: 0.75rem 1.5rem;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 1rem;
  font-weight: 500;
  transition: all 0.2s;
  min-width: 80px;
}

.demo-button.start {
  background-color: #28a745;
  color: white;
}

.demo-button.start:hover:not(:disabled) {
  background-color: #218838;
}

.demo-button.stop {
  background-color: #dc3545;
  color: white;
}

.demo-button.stop:hover:not(:disabled) {
  background-color: #c82333;
}

.demo-button.reset {
  background-color: #6c757d;
  color: white;
}

.demo-button.reset:hover {
  background-color: #5a6268;
}

.demo-button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.parent-simulation {
  background-color: #e8f5e9;
  padding: 1.5rem;
  border-radius: 6px;
}

.parent-simulation h4 {
  margin-top: 0;
  margin-bottom: 1rem;
  color: #2e7d32;
}

.status-info {
  margin-top: 1rem;
  padding: 1rem;
  background-color: white;
  border-radius: 4px;
  border-left: 3px solid #42b883;
}

.status-info p {
  margin: 0.5rem 0;
  color: #333;
}

.status-info strong {
  color: #42b883;
}

.code-examples {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
}

.code-section {
  background-color: #f8f9fa;
  padding: 1rem;
  border-radius: 6px;
}

.code-section h4 {
  margin-top: 0;
  margin-bottom: 1rem;
  color: #333;
}

.explanation {
  background-color: #e8f5e9;
  padding: 1.5rem;
  border-radius: 6px;
  border-left: 4px solid #4caf50;
  margin-bottom: 1.5rem;
}

.explanation h4 {
  margin-top: 0;
  margin-bottom: 1rem;
  color: #2e7d32;
}

.explanation ul {
  margin: 0;
  padding-left: 1.5rem;
}

.explanation li {
  margin-bottom: 0.5rem;
  color: #333;
}

.best-practices {
  background-color: #e3f2fd;
  padding: 1.5rem;
  border-radius: 6px;
  border-left: 4px solid #1976d2;
}

.best-practices h4 {
  margin-top: 0;
  margin-bottom: 1rem;
  color: #0d47a1;
}

.practice-tips {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1rem;
}

.tip-item {
  background-color: white;
  padding: 1rem;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.tip-item h5 {
  margin-top: 0;
  margin-bottom: 0.5rem;
  color: #1976d2;
}

.tip-item p {
  margin: 0;
  color: #666;
  font-size: 0.9rem;
}

/* 响应式布局 */
@media (max-width: 768px) {
  .timer-value {
    font-size: 2rem;
  }
  
  .timer-controls {
    flex-direction: column;
    align-items: center;
  }
  
  .demo-button {
    width: 100%;
    max-width: 200px;
  }
  
  .code-examples,
  .practice-tips {
    grid-template-columns: 1fr;
  }
}
</style>